package cn.sxt.logistics.controller;


import cn.sxt.logistics.pojo.Admin;
import cn.sxt.logistics.pojo.MessageObject;
import cn.sxt.logistics.pojo.ResultObject;
import cn.sxt.logistics.pojo.Role;
import cn.sxt.logistics.service.IAdminService;
import cn.sxt.logistics.service.IRoleService;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import org.springframework.stereotype.Controller;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author ${author}
 * @since 2020-06-13
 */
@Controller
@RequestMapping("/admin")
public class AdminController {


    @Autowired
    private IAdminService adminService;


    @Autowired
    private IRoleService roleService;



    /**
     * 在认证前强制访问某一个需要认证的页面或者
     * 认证过程中失败的时候跳转的页面
     *
     * */
    @RequestMapping("/login")
    public String login(HttpServletRequest request,Model model){
        //获取认证失败的错误信息（没有认证前强制访问一个需要认证的页面跳转过来是没有错误信息的null）
        String shiroLoginFailure = (String) request.getAttribute("shiroLoginFailure");
        if(StringUtils.isNotBlank(shiroLoginFailure)){

            if(UnknownAccountException.class.getName().equals(shiroLoginFailure)){
                model.addAttribute("errorMsg","亲，账号不存在！！！");
            }else if(IncorrectCredentialsException.class.getName().equals(shiroLoginFailure)){
                model.addAttribute("errorMsg","亲，密码错误！！！");
            }

        }

        return  "loginPage";
    }


    /*跳转到登录页面*/
    //@RequestMapping("/loginPage")
    @RequestMapping(path = "/loginPage")
    public String loginPage(){
        return  "loginPage";
    }



    @RequiresPermissions("admin:adminManager")
    @GetMapping("/adminManager")
    public String adminManager(){
        System.out.println("---------------: "+adminService);
        return "adminManager";
    }




    /**
     *
     * 返回给前端 BootStrapTable表格插件使用数据
     * 返回的数据格式总记录和当前页的结果集的json数据
     * 总记录的key ： total
     * 结果集的key ： rows
     *
     * @return
     */
    @RequestMapping("/list")
    @RequiresPermissions("admin:list")
    @ResponseBody
    public ResultObject list(@RequestParam(defaultValue = "1") Integer pageNum
                                  , @RequestParam(defaultValue = "10") Integer pageSize
                                    , String keyword){
        //分页对象
        Page<Admin> adminPage = new Page<Admin>(pageNum,pageSize);
        //条件对象
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();

        if(StringUtils.isNotBlank(keyword)){
            //根据姓名和账号模糊查询
            queryWrapper.like("username",keyword);
            //或者关系
            queryWrapper.or();
            queryWrapper.like("realname",keyword);

        }

        //查询结果
        Page<Admin> result = adminService.page(adminPage, queryWrapper);
        
        //获取当前页结果集
        List<Admin> admins = result.getRecords();
        //循环所有的管理员，根据当前循环的管理员根据管理员的id查询出对应的角色并返回角色对象，赋值给管理员
        for (Admin admin : admins) {
            //根据当前管理员的角色id查询出对应的角色对象
            Role role = roleService.getById(admin.getRoleId());
            //将角色对象设置给管理员
            admin.setRole(role);
        }


        return new ResultObject(result);
    }


    //删除功能
    @GetMapping("/delete")
    @RequiresPermissions("admin:delete")
    @ResponseBody
    public MessageObject delete(Long adminId){
        boolean flag = adminService.removeById(adminId);

        MessageObject mo = new MessageObject(1, "删除数据成功");
        if(!flag){
            mo = new MessageObject(0,"删除数据失败，请联系管理员");
        }
        return mo;
    }
    //删除功能
    @GetMapping("/deleteByAdminIds")
    @RequiresPermissions("admin:delete")
    @ResponseBody
    public MessageObject deleteByAdminIds(@RequestParam Long[] adminIds){
        System.out.println(Arrays.toString(adminIds));

        boolean flag = adminService.removeByIds(Arrays.asList(adminIds));

        MessageObject mo = new MessageObject(1, "批量删除数据成功");
        if(!flag){
            mo = new MessageObject(0,"批量删除数据失败，请联系管理员");
        }
        return mo;
    }

    /*跳转到编辑页面*/
    @GetMapping("/adminEdit")
    public String adminEdit(Model m,Long adminId){

        //如果有id说明是修改操作，需要查询出当前管理员的信息回显
        if(adminId !=null){
            Admin admin = adminService.getById(adminId);
            m.addAttribute("admin",admin);
        }


        //查询出所有的角色，以供新增修改的时候选择角色
        List<Role> roles = roleService.list();
        m.addAttribute("roles",roles);

        return "adminEdit";
    }

    /*新增数据*/
    @PostMapping("/insert")
    @RequiresPermissions("admin:insert")
    @ResponseBody
    public MessageObject insert(Admin admin){

        /*
        * 使用MD5+salt 加密三次设置密码
        * 把当前时间作为创建时间
        * */

        //使用随机数生成salt
        String salt = UUID.randomUUID().toString().substring(0,6);
        //密码进行加密
        Md5Hash md5Hash = new Md5Hash(admin.getPassword(), salt, 3);

        admin.setPassword(md5Hash.toString());
        admin.setSalt(salt);

        admin.setCreateDate(LocalDate.now());

        //新增管理员
        boolean flag = adminService.saveOrUpdate(admin);


        MessageObject mo = new MessageObject(1, "新增数据成功");
        if(!flag){
            mo = new MessageObject(0,"新增数据失败，请联系管理员");
        }
        return mo;
    }



    /*修改数据*/
    @PostMapping("/update")
    @RequiresPermissions("admin:update")
    @ResponseBody
    public MessageObject update(Admin admin){

        /*
         * 使用MD5+salt 加密三次设置密码
         * 把当前时间作为创建时间
         * */

        //使用随机数生成salt
        String salt = UUID.randomUUID().toString().substring(0,6);
        //密码进行加密
        Md5Hash md5Hash = new Md5Hash(admin.getPassword(), salt, 3);

        admin.setPassword(md5Hash.toString());
        admin.setSalt(salt);


        //新增管理员
        boolean flag = adminService.saveOrUpdate(admin);


        MessageObject mo = new MessageObject(1, "修改数据成功");
        if(!flag){
            mo = new MessageObject(0,"修改数据失败，请联系管理员");
        }
        return mo;
    }


    /*检查账号是否存在*/
    @PostMapping("/checkUsername")
    @RequiresPermissions("admin:checkUsername")
    @ResponseBody
    public boolean checkUsername(String username){
        QueryWrapper<Admin> querywrapper = new QueryWrapper<>();
        querywrapper.eq("username",username);
        Admin admin = adminService.getOne(querywrapper);
        return admin == null ? true : false;
    }

}

